/*
 *
 *
 */
package pkl51.component;

import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import pkl51.validasi.Validator;
import pkl51.view.FormUtama;

/**
 * charType ada 3 tipe 1 = INTEGER 2 = STRING (A-Z dan spasi) 3 = DOUBLE
 *
 * @author Kean
 */
public class TextField extends JFormattedTextField {

    private boolean focus;
    private boolean contain;
    private Color color;
    private Color focusColor;
    private Color containedColor;
    private Color lostColor;
    private int length;
    private int charType;
    private char maxDigit;
    private char minDigit;
    private Validator validator;
    private boolean required;

    public Validator getValidator() {
        return validator;
    }

    public void setValidator(Validator validator) {
        this.validator = validator;
    }

    public boolean isRequired() {
        return required;
    }

    public void setRequired(boolean required) {
        this.required = required;
    }

    public TextField() {
        setFocusTraversalKeysEnabled(false); //mematikan tombol tab/shift tab
        setOpaque(false);
        setBorder(new EmptyBorder(3, 6, 3, 6));
        setForeground(Color.BLACK);
        setSelectionColor(new Color(153, 0, 153));
        setCaretColor(Color.BLACK);
        setHorizontalAlignment(CENTER);
        setFocusColor(Color.WHITE);
        setLostColor(Color.white);
        setContainedColor(new Color(51, 255, 0));
        setFont(getFont().deriveFont(Font.BOLD));
        setLength(1);
        setCharType(1);
        setMaxDigit('9');
        setMinDigit('0');
        addFocusListener(new FocusAdapter() {

            @Override
            public void focusGained(FocusEvent e) {
                setFocus(true);
                selectAll();
            }

            @Override
            public void focusLost(FocusEvent e) {

                if (getText().equals("")) {
                    setFocus(false);
                    setContain(false);
                } else {
                    setFocus(false);
                    setContain(true);
                }
            }
        });
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                //proses validasi dijalankan ketika tombol enter/tab/panah bawah/panah kanan ditekan.
                if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_TAB) {
                    if ("".equals(TextField.this.getText().trim())) {
                        if (required) {
                            JOptionPane.showMessageDialog(FormUtama.getInstance(), "Field harus diisi", "Error", JOptionPane.ERROR_MESSAGE);
                            TextField.this.requestFocusInWindow();
                        } else {
                            TextField.this.transferFocus();
                        }
                    } else if (validator != null) {
                        boolean isValid = false;
                        isValid = validator.onCheckValue(TextField.this);
                        if (isValid) {
                            TextField.this.transferFocus();
                        } else {
                            TextField.this.requestFocusInWindow();
                        }
                    } else {
                        TextField.this.transferFocus();
                    }

                } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                    TextField.this.transferFocusBackward();
                }
            }
        });



        //Set contain

        setDocument(new PlainDocument() {

            @Override
            public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
                StringBuffer buffer = new StringBuffer();
                char[] cs = str.toCharArray();
                int s = 0;
                if (TextField.this.getText().length() < length) {
                    for (int i = 0; i < cs.length; i++) {
                        if (charType == 1) {
                            if (cs[i] >= minDigit && cs[i] <= maxDigit) {
                                cs[s++] = cs[i];
                            }
                        } else if (charType == 2) {
                            if (Character.isLetter(cs[i]) || cs[i] == ' ') {
                                cs[s++] = Character.toUpperCase(cs[i]);
                            }
                        } else if (charType == 3) {
                            if (Character.isDigit(cs[i])) {
                                cs[s++] = cs[i];
                            } else if (cs[i] == '.' && !TextField.this.getText().contains(".")) {
                                cs[s++] = cs[i];
                            }
                        } else {
                            cs[s++] = cs[i];
                        }
                    }
                    buffer.append(cs, 0, s);
                }
                super.insertString(offs, new String(buffer), a);
            }
        });

    }

    public int getCharType() {
        return charType;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    private boolean isFocus() {
        return focus;
    }

    private void setFocus(boolean focus) {
        this.focus = focus;
        repaint();
    }

    public boolean isContain() {
        return contain;

    }

    public void setContain(boolean contain) {
        this.contain = contain;
        repaint();
    }

    public Color getContainedColor() {
        return containedColor;
    }

    public void setContainedColor(Color containedColor) {
        this.containedColor = containedColor;
    }

    public Color getFocusColor() {
        return focusColor;
    }

    public void setFocusColor(Color focusColor) {
        this.focusColor = focusColor;
    }

    public Color getLostColor() {
        return lostColor;
    }

    public void setLostColor(Color lostColor) {
        this.lostColor = lostColor;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public char getMaxDigit() {
        return maxDigit;
    }

    public void setMaxDigit(char maxDigit) {
        this.maxDigit = maxDigit;
    }

    public char getMinDigit() {
        return minDigit;
    }

    public void setMinDigit(char minDigit) {
        this.minDigit = minDigit;
    }

    public void setCharType(int charType) {
        this.charType = charType;
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D gd = (Graphics2D) g.create();
        gd.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Paint paint;
        if (isFocus()) {
            paint = new GradientPaint(0, 0, new Color(focusColor.getRed(), focusColor.getGreen(),
                    focusColor.getBlue(), 255), 0, getHeight(), new Color(focusColor.getRed(), focusColor.getGreen(), focusColor.getBlue(), 150));
        } else {
            if (isEnabled()) {
                if (isContain()) {
                    paint = new GradientPaint(0, 0, new Color(containedColor.getRed(),
                            containedColor.getGreen(), containedColor.getBlue(), 255), 0,
                            getHeight(), new Color(containedColor.getRed(), containedColor.getGreen(), containedColor.getBlue(), 150));
                } else {
                    paint = new GradientPaint(0, 0, new Color(lostColor.getRed(),
                            lostColor.getGreen(), lostColor.getBlue(), 255), 0, getHeight(), new Color(lostColor.getRed(), lostColor.getGreen(), lostColor.getBlue(), 150));
                }
            } else {
                paint = new GradientPaint(0, 0, new Color(102, 153, 255), 0, getHeight(), new Color(102, 153, 255));
            }
        }
        gd.setPaint(paint);
        gd.fillRoundRect(0, 0, getWidth(), getHeight(), getHeight() / 2, getHeight() / 2);
        gd.setPaint(Color.BLACK);
//        gd.setStroke(new BasicStroke(1f));
        gd.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getHeight() / 2, getHeight() / 2);

        super.paintComponent(g);
        paint = new GradientPaint(0, 0, new Color(1F, 1F, 1F, 0.5F), 0, getHeight(), new Color(1F, 1F, 1F, 0.0F));
        gd.setPaint(paint);
        gd.fillRoundRect(0, 0, getWidth() - 1, getHeight() / 2, getHeight() / 2, getHeight() / 2);
//        gd.setStroke(new BasicStroke(1.5f));
//        gd.drawRoundRect(0, 0, getWidth()-2, getHeight()-1,getHeight()/2,getHeight()/2);
        gd.dispose();
    }

    public Integer getInt() {
        if (getText().equals("")) {
            return null;
        }
        try {
            Integer data = new Integer(getText());
            return data;
        } catch (NumberFormatException ex) {
            return null;
        }
    }

    public Integer getNol() {
        if (getText().equals("")) {
            return 0;
        }
        try {
            Integer data = new Integer(getText());
            return data;
        } catch (NumberFormatException ex) {
            return null;
        }
    }

    public void setInt(Integer data) {
        if (data == null) {
            setText(null);
        } else {
            String str = data.toString();
            setText(str);
        }
    }

    @Override
    public boolean requestFocusInWindow() {
        if (!isEnabled()) {
            setEnabled(true);
        }
        return super.requestFocusInWindow();
    }
}